package com.artup.service.impl;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.artup.common.Constants;
import com.artup.common.ResponseResult;
import com.artup.dao.AuthorityDao;
import com.artup.dao.UserDao;
import com.artup.pojo.Resource;
import com.artup.pojo.User;
import com.artup.service.AuthorityService;
import com.artup.util.CommonUtils;
import com.artup.util.md5.MD5Util2;
import com.artup.util.md5.MD5Utils;

@Service( value = "authorityService" )
@Transactional( readOnly = false )
public class AuthorityServiceImpl implements AuthorityService {
	protected static final Logger LOGGER = LoggerFactory.getLogger(AuthorityServiceImpl.class);
	
	@Autowired
	private AuthorityDao authorityDao;

	@Autowired
	private UserDao userDao;

	@Override
	public ResponseResult signin(String username, String password, String securityCode, String clientIP, HttpSession httpSession ) {
		LOGGER.info("username = " + username + ", clientIP = " + clientIP);
		
		ResponseResult responseResult = new ResponseResult();
		
		if(StringUtils.isBlank(securityCode)) {
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("请输入验证码！");
			
			return responseResult;
		} 
		if( null == httpSession.getAttribute(httpSession.getId()) ) {
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("验证码已失效！请重新获取。");
			
			return responseResult;
		} 
		if(!httpSession.getAttribute(httpSession.getId()).equals(securityCode)) {
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("验证码不正确！");
			
			return responseResult;
		}
		
		User user = null;
		try {
			user = this.userDao.selectUserByUsername(username);
		} catch (Exception e) {
			LOGGER.error("根据【用户名】查询【用户】 - 失败！", e);
			
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("根据【用户名】查询【用户】 - 失败！");
		}
		
		if(null == user) {
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("用户名或密码错误！");
			
			return responseResult;
		}
		
		try {
			if(!MD5Util2.validPassword(password, user.getPassword())) {
				responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
				responseResult.setMessage("用户名或密码错误！");
				
				return responseResult;
			}
		} catch (ArrayIndexOutOfBoundsException | NoSuchAlgorithmException | UnsupportedEncodingException e) {
			LOGGER.error("密码校验错误", e);
		}
		
		// TODO 用户足记记录到 MongoDB 中
		List<Resource> resourceList = null;
		try {
			resourceList = this.authorityDao.selectValidResourceListByUserId(user.getId());
		} catch (Exception e) {
			LOGGER.error("根据【用户ID】查询有效的【资源列表】 - 失败！", e);
			
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("根据【用户ID】查询有效的【资源列表】 - 失败！");
		}
		
		httpSession.setAttribute("user", user);	// 放入到 HTTP 会话中
		httpSession.setAttribute("resources", this.setResourceLevel(resourceList));	// 放入到 HTTP 会话中
		
		responseResult.setStatus(Constants.ACTION_STATUS_SUCCESS);
		responseResult.setData(this.setResourceLevel(resourceList));
		responseResult.setMessage("登入成功。");
		
		return responseResult;
	}

	@Override
	public ResponseResult register(String username, String password, String nickname, String securityCode, String clientIP, HttpSession httpSession ) {
		LOGGER.info("username = " + username + ", clientIP = " + clientIP);
		
		ResponseResult responseResult = new ResponseResult();
		
		if(StringUtils.isBlank(securityCode)) {
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("请输入验证码！");
			
			return responseResult;
		} else if(!httpSession.getAttribute(httpSession.getId()).equals(securityCode)) {
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("验证码不正确！");
			
			return responseResult;
		}
		
		User user = null;
		try {
			user = this.userDao.selectUserByUsername(username);
		} catch (Exception e) {
			LOGGER.error("根据【用户名】查询【用户】 - 失败！", e);
			
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("根据【用户名】查询【用户】 - 失败！");
		}
		
		if(null != user) {
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("用户名已存在！");
			
			return responseResult;
		}
		
		user = new User();
		user.setUsername(username);
		try {
			user.setPassword(MD5Utils.getEncryptedPasswordd(password));
		} catch (NoSuchAlgorithmException e) {
			LOGGER.error("没有这样的运算 - 失败！", e);
			
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("密码加密 - 失败！");
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("不支持的字符编码 - 失败！", e);
			
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("密码加密 - 失败！");
		}
		user.setNickname(nickname);
		try {
			this.userDao.insertUser(user);
		} catch (Exception e) {
			LOGGER.error("保存【用户】 - 失败！", e);
			
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("保存【用户】 - 失败！");
		}
		
		responseResult.setStatus(Constants.ACTION_STATUS_SUCCESS);
		responseResult.setMessage("注册成功。");
		
		return responseResult;
	}

	@Override
	public ResponseResult logout( String username ) {
		LOGGER.info("username = " + username);
		
		ResponseResult responseResult = new ResponseResult();
		
		HttpSession httpSession = getRequest().getSession();
		
		httpSession.removeAttribute("user");	// 从 HTTP 会话中移除当前用户信息
		httpSession.removeAttribute("resources");	// 将“资源列表”从会话中清除
		
		responseResult.setStatus(Constants.ACTION_STATUS_SUCCESS);
		responseResult.setMessage("退出成功。");
		
		return responseResult;
	}
	
	public static HttpServletRequest getRequest() { 
	    ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
	    
	    return servletRequestAttributes.getRequest(); 
	} 

	/**
	 * 设置【资源】的级别
	 * @param resourceList
	 * @return
	 */
	private List<Resource> setResourceLevel(List<Resource> resourceList) {
		if(CommonUtils.isEmpty(resourceList)) {
			return null;
		}
		
		List<Resource> firstResourceList = new ArrayList<Resource>();
		List<Resource> secondResourceList = new ArrayList<Resource>();
		
		for(Resource resource : resourceList) {
			if(null == resource) {
				continue;
			}
			
			if(1 == resource.getLevel()) {
				firstResourceList.add(resource);
			} else if(2 == resource.getLevel()) {
				secondResourceList.add(resource);
			}
		}
		
		if(CommonUtils.isNotEmpty(firstResourceList)) {
			for(Resource firstResource : firstResourceList) {
				List<Resource> subResourceList = new ArrayList<Resource>();
				firstResource.setSubResourceList(subResourceList);
				
				for(Resource secondResource : secondResourceList) {
					if(null == secondResource) {
						continue;
					}
					
					if(firstResource.getId() == secondResource.getParentId()) {
						subResourceList.add(secondResource);
					}
				}
			}
		}
		
		return firstResourceList;
	}
}
